using System;
using System.ComponentModel;
using System.Deployment.Application;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows;

namespace OrbitOne.CRMLyncInfoDashboard.Setup
{
    public class Controller : IController, INotifyPropertyChanged, IDataErrorInfo
    {
        public const string UrlRegex = @"^((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]+)$";

        public IInstallCommand InstallCommand { get; private set; }
        public IUninstallCommand UninstallCommand { get; private set; }
        public IDashboardInstaller DashboardInstaller { get; private set; }
        public string InstallButtonContent
        {
            get
            {
                return DashboardInstaller.IsInstalled()
                           ? "Re-install the CRM Dashboard in the Lync client"
                           : "Install the CRM Dashboard in the Lync client";

            }
        }

        private string m_url;
        public string Url
        {
            get { return m_url; }
            set
            {
                m_url = value;
                InstallCommand.Refresh();
                NotifyPropertyChanged("Url");
            }
        }

        public Controller()
        {

            DashboardInstaller = new DashboardInstaller(this);
            InstallCommand = new InstallCommand(this);
            UninstallCommand = new UninstallCommand(this);
            PreloadCrmServerUrl();

        }

        private void PreloadCrmServerUrl()
        {
            if (!ApplicationDeployment.IsNetworkDeployed) return;


            if (ApplicationDeployment.CurrentDeployment.ActivationUri != null)
            {

                var queryString = ApplicationDeployment.CurrentDeployment.ActivationUri.Query;


                if (!HasActivationData(queryString))
                {
                    return;
                }
                var crmServerUrl = GetCrmServerUrl(queryString);

                SetUrl(crmServerUrl);
            }

        }

        private void SetUrl(string crmServerUrl)
        {
            if (!string.IsNullOrWhiteSpace(crmServerUrl))
            {
                Url = crmServerUrl;
            }
        }

        private static string GetCrmServerUrl(string activationData)
        {
            var nvc = HttpUtility.ParseQueryString(activationData);
            return nvc.AllKeys.Contains("crmServerUrl") ? nvc["crmServerUrl"] : "";
        }

        private static bool HasActivationData(string activationData)
        {
            return !string.IsNullOrWhiteSpace(activationData);
        }


        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public string this[string columnName]
        {
            get
            {
                return PropertyNotValid(columnName, "Url", IsUrlValid)
                           ? "The CRM server URL is mandatory for the installation."
                           : null;
            }
        }
        private bool PropertyNotValid(string columnName, string expectedColumnName, Func<bool> isValidPredicate)
        {
            return columnName == expectedColumnName && !isValidPredicate();
        }

        public string Error
        {
            get { return null; }
        }

        public bool IsUrlValid()
        {
            return !string.IsNullOrWhiteSpace(Url)
                && Regex.IsMatch(Url, UrlRegex);
        }
    }
}